﻿using System;
using System.Collections.Generic;
using System.Linq;
using GameEngine.Scenes;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using GuiLibrary.Components;

namespace GuiLibrary.layouts
{
    public class ListLayout:Layout
    {
        public bool isVertical { get; set; }
        public float[] weights;

        public ListLayout(Panel parentPanel, int[] margins, float[] weight, bool isVertical, IOnElementSelected onComponentSelected, IOnCancel onCancel, IOnElementPointed onComponentPointed) :
            base(parentPanel, margins, onComponentSelected, onCancel, onComponentPointed) 
        {
            this.isVertical = isVertical;
            this.weights = weight;
        }
        public ListLayout(Panel parentPanel, int[] margins, bool isVertical, IOnElementSelected onComponentSelected, IOnCancel onCancel, IOnElementPointed onComponentPointed) :
            base(parentPanel, margins, onComponentSelected, onCancel, onComponentPointed) 
        {
            this.isVertical = isVertical;
            this.weights = new float[parentPanel.components.Count];
            for (int i = 0; i < weights.Count(); i++) 
            {
                weights[i] = 1;
            }
        }
        public override bool canMove(Layout.Cursor cursor)
        {
            bool down = false, up = false;
            switch (cursor)
            {
                case Cursor.DOWN:
                    down = true;
                    goto case Cursor.RIGHT;
                case Cursor.RIGHT:
                    if (isVertical == down && pointedElement < getComponents().Count - 1)
                        //if it's vertical and pressing down or if it's not vertical and pressing right, also check bounds
                        return true;
                    else
                        return false;
                case Cursor.UP:
                    up = true;
                    goto case Cursor.LEFT;
                case Cursor.LEFT:
                    if (isVertical == up && pointedElement > 0)
                        //if it's vertical and pressing up or if it's not vertical and pressing left, also check bounds
                        return true;
                    else
                        return false;
            }
            return true;
        }
        public override void moveCursor(Cursor cursor) 
        {
            bool down = false, up = false;
            switch (cursor) 
            {
                case Cursor.DOWN:
                    down = true;
                    goto case Cursor.RIGHT;
                case Cursor.RIGHT:
                    if (isVertical == down && pointedElement < getComponents().Count - 1)
                        //if it's vertical and pressing down or if it's not vertical and pressing right, also check bounds
                    {
                        changePointedComponent(pointedElement + 1);
                    }
                    break;
                case Cursor.UP:
                    up = true;
                    goto case Cursor.LEFT;
                case Cursor.LEFT:
                    if (isVertical == up && pointedElement > 0)
                        //if it's vertical and pressing up or if it's not vertical and pressing left, also check bounds
                    {
                        changePointedComponent(pointedElement - 1);
                    }
                    break;
            }
            base.moveCursor(cursor);
        }
        public override void refresh()
        {
            Vector2 panelSize = parentPanel.getSize()
                - new Vector2(marginLeft,marginTop) - new Vector2(marginRight, marginDown); //consider margins
            //int cellHeight = (int)(sceneSize.Y / getComponents().Count); used before considering weights
            float currentHeight = 0; //if it's not vertical this is used in horizontal axis
            int i = 0;
            foreach (Component component in getComponents())
            {
                component.relativePosition = (isVertical ? new Vector2(0, currentHeight) : new Vector2(currentHeight, 0))
                    + new Vector2(marginLeft, marginTop);   //considering margins
                component.refresh();

                currentHeight += (isVertical ? panelSize.Y : panelSize.X) * weights[i] / weights.Sum();
                i++;
            }
            //getComponents()[selectedElement].isFlashing = true;
            refreshPointedComponent();
        }
        public override Vector2 getComponentSize(Component component)
        {
            Vector2 panelSize = parentPanel.getSize()
                - new Vector2(marginLeft, marginTop) - new Vector2(marginRight, marginDown); //consider margins
            float currentHeight = 0, currentWidth = 0;
            List<Component> components = getComponents();
            for (int i = 0; i < components.Count; i++) 
            {
                if (components[i] == component) 
                {
                    return new Vector2((isVertical?panelSize.X:panelSize.X* weights[i] / weights.Sum()),
                        (isVertical?panelSize.Y* weights[i] / weights.Sum():panelSize.Y));
                }
                currentHeight += (isVertical ? panelSize.Y : 0) * weights[i] / weights.Sum();//if vertical move to the next row
                currentWidth += (isVertical ? 0 : panelSize.X) * weights[i] / weights.Sum();//if horizontal move to the next col
            }
            return new Vector2();
        }
        public override void eraseComponent(int componentIndex)
        {
            float erasedWeight = weights[componentIndex];
            float eachOtherAdd = erasedWeight/(weights.Sum()-1);
            float[] newWeights = new float[weights.Length-1];
            int lastIndex = 0;
            for (int i = 0; i < weights.Length; i++)
            {
                if (i != componentIndex)
                {
                    newWeights[lastIndex] = weights[i]+eachOtherAdd;
                    lastIndex++;
                }
            }
            weights = newWeights;
        }
    }
}
